package com.xbh.common.model;

import com.alibaba.fastjson.annotation.JSONField;
import jodd.util.StringUtil;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by Doaim on 2017/4/20.
 */
public abstract class BaseModel {
    @JSONField(serialize = false)
    private static final Map<Class, ModelMetaData> metaDataMap = new ConcurrentHashMap<>();

    public static ModelMetaData getMetaData(Class clazz){
        ModelMetaData metaData = metaDataMap.get(clazz);
        if(metaData == null){
            Table table = (Table) clazz.getAnnotation(Table.class);
            synchronized (clazz) {
                metaData = metaDataMap.get(clazz);;
                if(metaData != null){
                    System.out.println("同步锁生效");
                    return metaData;
                }
                metaData = new ModelMetaData();
                if (table != null) {
                    metaData.setTableName(table.name());
                }
                List<Class> classList = new ArrayList<>();
                classList.add(clazz);
                Class superClass;
                while ((superClass = clazz.getSuperclass()) != null) {
                    classList.add(superClass);
                    clazz = superClass;
                }
                for (Class clazzz : classList) {
                    for (Field field : clazzz.getDeclaredFields()) {
                        Column column = field.getAnnotation(Column.class);
                        if (column != null) {
                            String columnName = column.name();
                            if (StringUtil.isEmpty(columnName)) {
                                columnName = field.getName();
                            }
                            field.setAccessible(true);
                            if (field.getAnnotation(Id.class) != null) {
                                metaData.setIdColumnMapping(field,columnName);
                            }else{
                                metaData.setColumnMapping(field, columnName);
                            }
                        }
                    }
                }
                metaDataMap.put(clazz, metaData);
            }
        }
        return metaData;
    }
}
